import React, { useState, useEffect } from 'react';
import { Drawer, Tag, Space } from 'antd';
import { connect, Dispatch } from 'umi';
import { MENU_INIT,
  MENU_LIST,
  MENU_ADD,
  MENU_UPDATE,
  MENU_DELETE,
  UPDATE_STATE } from '@/actions/menu';
import ProCard from '@ant-design/pro-card';
import ProDescriptions, { ProDescriptionsItemProps } from '@ant-design/pro-descriptions';
import {PageContainer } from '@ant-design/pro-layout';
import AGrid, { AGridButtonCallBackModel } from '@/components/SelfComp/AGrid';
import { ConnectState } from '@/models/connect';
import { DataItem } from '@/models/common';
import { getItemValue } from '@/utils/commons';
import MenuQueryForm from './components/MenuQueryForm';
import AddMenuModal from './components/AddMenuModal';
import UpdateMenuModal from './components/UpdateMenuModal';
import { MenuItem, MenuSelectTreeItem } from './data';

interface MenuListProps {
  dispatch: Dispatch;
  menuList: MenuItem[],
  total: number,
  loading: boolean;
  pageSize: number;
  addLoading: boolean;
  updateLoading: boolean;
  menuTypeData: DataItem[];
  menuActionData: DataItem[];
  statusData: DataItem[];
  hideInMenuData: DataItem[];
}

const EMPTY_MENU: MenuItem = {
  menuId: '',
  parentMenuId: '',
  menuCode: '',
  menuName: '',
  menuPath: '',
  menuType: '',
  hideInMenu: '',
  menuStates: '',
  menuAction: '',
  menuSort: '',
  menuAlias: '',
  children: []
}

/**
   * 根据全量菜单数据生成下拉框菜单树形数据，过滤掉按钮
   * @param {Array} menuList 全量菜单数据
   * @returns 下拉框菜单树形数据
   */
const generatorMenuTreeData = (menuList: MenuItem[] = []): MenuSelectTreeItem[] => {
  return menuList.map(menu => {
    if (menu.children) {
      const newMenu: MenuSelectTreeItem = {
        value: menu.menuId,
        title: menu.menuName,
        children: generatorMenuTreeData(menu.children.filter(childMenu => childMenu.menuType === '0' || childMenu.menuType === '1' || childMenu.menuType === '3'))
      };
      return newMenu;
    } else {
      const newMenu: MenuSelectTreeItem = {
        value: menu.menuId,
        title: menu.menuName
      };
      return newMenu;
    }
  });
}

/**
 * 菜单列表管理
 * @param props 属性
 * @returns 菜单列表
 */
const MenuList: React.FC<MenuListProps> = (props) => {
  const code = 'menu-list';
  const { menuList, loading, menuTypeData, menuActionData, hideInMenuData, addLoading, updateLoading } = props;
  const [addModalVisible, handleAddModalVisible] = useState<boolean>(false);
  const [updateModalVisible, handleUpdateModalVisible] = useState<boolean>(false);
  const [row, setRow] = useState<MenuItem>();
  const [selectedRowKeys, setSelectedRowKeys] = useState<React.Key[]>([]);
  const [selectedRows, setSelectedRows] = useState<MenuItem[]>([]);
  const [queryParam, setQueryParam] = useState<MenuItem>(EMPTY_MENU);
  const [pageSize, setPageSize] = useState<number>(10);
  const [menuFormData, setMenuFormData] = useState<MenuItem>(EMPTY_MENU);
  // menuList过滤掉按钮，只保留菜单
  const menuTreeData = generatorMenuTreeData(menuList);
  const rowKey = (record: MenuItem) => {
    return record.menuId;
  }
  const pkField = 'userId';
  const columns = [
    {
      title: '菜单名称',
      dataIndex: 'menuName',
      width: 180,
      render: (text: string, record: MenuItem, index: number) => {
        return <a onClick={() => setRow(record)}>{text}</a>;
      },
    },
    {
      title: '菜单图标',
      dataIndex: 'menuIcon',
      width: 200

    },
    {
      title: '菜单编号',
      dataIndex: 'menuCode',
      width: 130
    },
    {
      title: '菜单别名',
      dataIndex: 'menuAlias',
      width: 100
    },
    {
      title: '菜单类型',
      dataIndex: 'menuType',
      render: (text: string, record: MenuItem, index: number) => menuTypeFunc(record),
      width: 80
    },
    {
      title: '菜单是否显示',
      dataIndex: 'hideInMenu',
      render: (text: string, record: MenuItem, index: number) => hideInMenuFunc(record),
      width: 120
    },
    {
      title: '路由地址',
      dataIndex: 'menuPath',
      width: 250,
      ellipsis: true
    },
    {
      title: '按钮功能',
      dataIndex: 'menuAction',
      render: (text: string, record: MenuItem, index: number) => menuActionFunc(record),
      width: 120
    },
    {
      title: '排序',
      dataIndex: 'menuSort',
      width: 80
    }
  ];

  useEffect(() => {
    console.info('MenuList.useEffect');
    const { dispatch } = props;
    dispatch(MENU_INIT({}));
    return () => {
      const { dispatch } = props;
      dispatch(UPDATE_STATE({
        menuList: []
      }));
    }
  }, []);

  const menuTypeFunc = (record: MenuItem) => {
    const { menuTypeData } = props;
    const { menuType } = record;
    const value = getItemValue(menuTypeData, menuType);
    return <Tag color='processing'>{value}</Tag>
  }

  const hideInMenuFunc = (record: MenuItem) => {
    const { hideInMenuData } = props;
    const { hideInMenu } = record;
    const value = getItemValue(hideInMenuData, hideInMenu);
    if (hideInMenu === '1') {
      return <Tag color='error'>{value}</Tag>;
    }
    return <Tag color='processing'>{value}</Tag>;
  }

  const menuActionFunc = (record: MenuItem) => {
    const { menuActionData } = props;
    const { menuAction } = record;
    if (!menuAction) {
      return '';
    }
    const value = getItemValue(menuActionData, menuAction);
    return <Tag color='processing'>{value}</Tag>
  }

  /**
   * 查询满足条件的数据字典
   */
  const handleQuery = (record: MenuItem) => {
    console.info('MenuList.handleQuery');
    console.info(record);
    const queryParam = {
      ...record
    };
    // 查询条件保存起来，方便点击页码时使用
    // setState回调方法，保证先更新state
    fetchAllMenu(1, pageSize, queryParam);
  }

  const handleReset = () => {
    // 是否清空表格
  }

  /**
   * 分页查询系统参数信息
   * @param {*} pageNum 页码
   * @param {*} pageSize 每页记录条数
   */
  const fetchAllMenu = (pageNum: number, pageSize: number, queryParam: MenuItem) => {
    const { dispatch } = props;
    dispatch(MENU_LIST({
      ...queryParam,
      pageSize,
      pageNum
    }));
  }

  /**
   * 删除菜单
   * @param userId 菜单id
   */
  const deleteMenus = async (keys: React.Key[]) => {
    const { dispatch } = props;
    const res = await dispatch(MENU_DELETE(keys));
    if (res) {
      dispatch(MENU_LIST({
        ...queryParam,
        pageSize,
        pageNum: 1,
      }));
    }
  }

  /**
   * 处理按钮点击回调事件
   * @param {*} payload 数据包
   */
  const handleBtnCallBack = (callBackModel: AGridButtonCallBackModel<MenuItem>) => {
    console.log('handleBtnCallBack');
    console.log(callBackModel);
    // btn 按钮
    // keys 表格勾选数组
    const { btn } = callBackModel;
    const { alias } = btn;
    // 新增
    if (alias === 'add') {
      handleAddModalVisible(true);
      return;
    }
    // 修改
    if (alias === 'edit') {
      const { rows } = callBackModel;
      setMenuFormData(rows[0]);
      handleUpdateModalVisible(true);
      return;
    }
    // 删除
    if (alias === 'delete') {
      const { keys } = callBackModel;
      // 调用删除服务，删除勾选数据
      deleteMenus(keys);
      return;
    }
  }

  /**
   * 表格勾选回调函数
   * @param {*} rows 表格选中数据集合
   */
  const onSelectRow = (keys: React.Key[], rows: MenuItem[]) => {
    setSelectedRowKeys(keys);
    setSelectedRows(rows);
  };

  const handleAddModal = async (record: MenuItem) => {
    console.log(record);
    const { dispatch } = props;
    console.info(dispatch);
    const res = await dispatch(MENU_ADD(record));
    console.info(res);
    if (res) {
      handleAddModalVisible(false);
      fetchAllMenu(1, pageSize, queryParam);
    }
  }

  const handleAddModalCancel = () => {
    handleAddModalVisible(false);
  };

  /**
   * 更新面板的确定事件
   * @param {*} record 更新表单
   */
  const handleUpdateModal = async (record: MenuItem) => {
    console.log('handleUpdateModalOk');
    console.log(record);
    console.info(menuFormData);
    const { dispatch } = props;
    const res = await dispatch(MENU_UPDATE(record));
    console.info(res);
    if (res) {
      handleUpdateModalVisible(false);
      setMenuFormData(EMPTY_MENU);
      fetchAllMenu(1, pageSize, queryParam);
    }
  }

  const handleUpdateModalCancel = () => {
    handleUpdateModalVisible(false);
    setMenuFormData(EMPTY_MENU);
  };

  return (
    <PageContainer>
      <Space direction='vertical' size='middle' style={{ display: 'flex' }}>
        <ProCard title='查询条件' headerBordered >
          <MenuQueryForm
            colon={false}
            loading={loading}
            onSubmit={(record) => {
              setQueryParam(record);
              handleQuery(record);
            }}
            onReset={handleReset}
          />
        </ProCard>
        <ProCard>
          <AGrid
            code={code}
            btnCallBack={handleBtnCallBack}
            columns={columns}
            rowKey={rowKey}
            pkField={pkField}
            dataSource={menuList}
            loading={loading}
            onSelectRow={onSelectRow}
            scroll={{x:1600}}
            actionColumnFixed='right'
          />
        </ProCard>
      </Space>
      {
        !addModalVisible ? null :
        <AddMenuModal
          menuTypeData={menuTypeData}
          menuActionData={menuActionData}
          hideInMenuData={hideInMenuData}
          menuTreeData={menuTreeData}
          colon={false}
          modalTitle='新增菜单'
          modalWidth={1000}
          modalVisible={addModalVisible}
          loading={addLoading}
          onHandlerOK={handleAddModal}
          onHandlerCancel={handleAddModalCancel}
        />
      }
      {
        !updateModalVisible ? null :
        <UpdateMenuModal
          menuTypeData={menuTypeData}
          menuActionData={menuActionData}
          hideInMenuData={hideInMenuData}
          menuTreeData={menuTreeData}
          colon={false}
          modalTitle=''
          modalWidth={1000}
          modalVisible={updateModalVisible}
          flag='edit'
          loading={updateLoading}
          formData={menuFormData}
          onHandlerOK={handleUpdateModal}
          onHandlerCancel={handleUpdateModalCancel}
        />
      }
      <Drawer
        width={600}
        open={!!row}
        onClose={() => {
          setRow(undefined);
        }}
        closable={false}
      >
        {row?.menuId && (
          <ProDescriptions<MenuItem>
            column={2}
            title={row?.menuName}
            request={async () => ({
              data: row || {},
            })}
            params={{
              id: row?.menuId,
            }}
            columns={columns as ProDescriptionsItemProps<MenuItem>[]}
          />
        )}
      </Drawer>
    </PageContainer>
  );
};

export default connect((state: ConnectState) => ({
  menuList: state.menus.menuList,
  menuTypeData: state.menus.menuTypeData,
  menuActionData: state.menus.menuActionData,
  hideInMenuData: state.menus.hideInMenuData,
  loading: state.loading.effects['menus/fetchAllMenu'],
  addLoading: state.loading.effects['menus/addMenu'],
  updateLoading: state.loading.effects['menus/updateMenu'],
}))(MenuList);